#include "tts.h"

#include <thread>

using namespace std;

TTS::TTS()
{
	m_pSpVoice = NULL;
}

TTS::~TTS()
{
	Dispose();
}

bool TTS::Init()
{
	if (m_pSpVoice != NULL)
	{
		m_pSpVoice->Release();
		m_pSpVoice = NULL;
	}

	HRESULT hr = CoInitialize(NULL);
	hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void**)&m_pSpVoice);
	return SUCCEEDED(hr);
}

void TTS::Dispose()
{
	if (m_pSpVoice != NULL)
	{
		m_pSpVoice->Release();
		m_pSpVoice = NULL;
	}
	CoUninitialize();
}

bool TTS::Rate(long rate)
{
	if (m_pSpVoice != NULL)
	{
		HRESULT hr = m_pSpVoice->SetRate(rate);
		return SUCCEEDED(hr);
	}
	else
	{
		return false;
	}
}

bool TTS::Speak(std::string str)
{
	if (m_pSpVoice != NULL)
	{
		std::wstring wstr = StringToWString(str);

		/*HRESULT hr = m_pSpVoice->Speak(wstr.c_str(), SPF_DEFAULT, NULL);
		return SUCCEEDED(hr);*/

		thread tsp(&TTS::threadSpeak, this, wstr);
		tsp.detach();
		return true;
	}
	else
	{
		return false;
	}
}

void TTS::threadSpeak(std::wstring wstr)
{
	if (m_pSpVoice != NULL)
	{
	    CoInitialize(NULL);
		m_pSpVoice->Speak(wstr.c_str(), SPF_DEFAULT, NULL);
		//CoUninitialize();
	}
}

std::wstring TTS::StringToWString(std::string str)
{
	/*int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
	wchar_t* wide = new wchar_t[len + 1];
	memset(wide, '\0', sizeof(wchar_t) * (len + 1));
	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wide, len);
	std::wstring w_str(wide);
	delete[] wide;
	return w_str;*/

	std::wstring wszStr;
	int nLength = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, NULL);
	wszStr.resize(nLength);
	LPWSTR lpwszStr = new wchar_t[nLength];
	MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, lpwszStr, nLength);
	wszStr = lpwszStr;
	delete[] lpwszStr;
	return wszStr;
}
